package com.hy.fangZhou.iot;

import com.github.signalr4j.client.hubs.HubProxy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.hy.fbox.LoggerFactory;
import com.hy.fbox.TokenManager;
import com.hy.fbox.models.BoxStateChanged;
import com.hy.fbox.signalr.SignalRConnectionBase;
import com.hy.fangZhou.websocket.WebSocketMsg;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.Proxy;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;

public class FBoxSignalRConnection extends SignalRConnectionBase {
    private final Gson gson;
    ConcurrentHashMap<Long, LongAdder> dmonIds = new ConcurrentHashMap<>();
    private LongAdder dmonMsgCounter = new LongAdder();
    private Proxy proxy;
    private LongAdder dmonItemCounter = new LongAdder();

    public FBoxSignalRConnection(String hubUrl, String signalrClientId, TokenManager tokenManager, Proxy proxy, LoggerFactory loggerFactory) {
        super(hubUrl, signalrClientId, tokenManager, proxy, loggerFactory);
        this.proxy = proxy;
        gson = new GsonBuilder().create();
    }

    @Override
    public void connected() {
        super.connected();
        dmonIds.clear();
    }

    protected void onHubProxyDestroyed(HubProxy hubProxy) {
        hubProxy.removeSubscription("dmonUpdateValue");
    }

    @Resource
    private WebSocketMsg webSocketMsg;

    @Override
    protected void onHubProxyCreated(HubProxy hubProxy) {

        //signalr实时数据推送事件，接收此事件数据前提条件，开启监控点数据推送控制接口（订阅）
        hubProxy.subscribe("dmonUpdateValue").addReceivedHandler(jsonElements -> {
            Global.threadPool.submit(() -> {
                this.dmonMsgCounter.increment();
                //收到的推送数据
                JsonArray items = jsonElements[1].getAsJsonArray();
                String boxId = jsonElements[2].getAsString();

                for (com.google.gson.JsonElement jsonElement : items) {
                    JsonObject item = jsonElement.getAsJsonObject();
                    this.dmonIds.computeIfAbsent(item.get("id").getAsLong(), aLong -> new LongAdder()).increment();
                    this.dmonItemCounter.increment();
                    //收到的推送数据
                    String name = item.get("name").getAsString();
                    String value = item.get("value").getAsString();

                    // 收集数据
                    switch (name) {
                        case "循环水箱温度":
                            webSocketMsg.sendData("circulatingWaterTankTemperature", value, boxId, 0, 1);
                            break;
                        case "循环水箱入水口温度":
                            webSocketMsg.sendData("circulatingWaterTankInletTemperature", value, boxId, 0, 1);
                            break;
                        case "冷却塔进水温度":
                            webSocketMsg.sendData("coolingTowerInletTemperature", value, boxId, 0, 1);
                            break;
                        case "冷却塔出水温度":
                            webSocketMsg.sendData("coolingTowerOutletTemperature", value, boxId, 0, 1);
                            break;
                        case "热水箱温度":
                            webSocketMsg.sendData("hotWaterTankTemperature", value, boxId, 0, 1);
                            break;
                        case "填料温度":
                            webSocketMsg.sendData("fillingTemperature", value, boxId, 0, 1);
                            break;
                        case "冷却塔循环水流量":
                            webSocketMsg.sendData("coolingTowerWaterFlowRate", value, boxId, 0, 1);
                            break;
                        case "干球温度目标值":
                            webSocketMsg.sendData("dryBulbTemperatureTarget", value, boxId, 0, 1);
                            break;
                        case "湿球温度目标值":
                            webSocketMsg.sendData("wetBulbTemperatureTarget", value, boxId, 0, 1);
                            break;
                        case "循环水箱液位":
                            webSocketMsg.sendData("circulatingWaterTankLiquidLevel", value, boxId, 0, 2);
                            break;
                        case "冷却塔进水口压力":
                            webSocketMsg.sendData("coolingTowerInletPressure", value, boxId, 0, 3);
                            break;
                        case "冷却塔出水口压力":
                            webSocketMsg.sendData("coolingTowerOutletPressure", value, boxId, 0, 3);
                            break;
                        case "小循环泵备用流量":
                            webSocketMsg.sendData("smallCirculationPumpBackupFlowRate", value, boxId, 0, 1);
                            break;
                        case "小循环泵备用压力":
                            webSocketMsg.sendData("smallCirculationPumpBackupPressure", value, boxId, 0, 3);
                            break;
                        case "加热泵运行频率":
                            webSocketMsg.sendData("heatingPumpOperatingFrequency", value, boxId, 2, 2);
                            break;
                        case "加热泵运行电流":
                            webSocketMsg.sendData("heatingPumpOperatingCurrent", value, boxId, 2, 2);
                            break;
                        case "加热泵运行功率":
                            webSocketMsg.sendData("heatingPumpOperatingPower", value, boxId, 1, 1);
                            break;
                        case "循环泵运行频率":
                            webSocketMsg.sendData("circulationPumpOperatingFrequency", value, boxId, 2, 2);
                            break;
                        case "循环泵运行电流":
                            webSocketMsg.sendData("circulationPumpOperatingCurrent", value, boxId, 2, 2);
                            break;
                        case "循环泵运行功率":
                            webSocketMsg.sendData("circulationPumpOperatingPower", value, boxId, 1, 1);
                            break;
                        case "A相电流":
                            webSocketMsg.sendData("phaseACurrent", value, boxId, 0, 2);
                            break;
                        case "B相电流":
                            webSocketMsg.sendData("phaseBCurrent", value, boxId, 0, 2);
                            break;
                        case "C相电流":
                            webSocketMsg.sendData("phaseCCurrent", value, boxId, 0, 2);
                            break;
                        case "Uab线电压":
                            webSocketMsg.sendData("lineVoltageUab", value, boxId, 0, 1);
                            break;
                        case "Ubc线电压":
                            webSocketMsg.sendData("lineVoltageUbc", value, boxId, 0, 1);
                            break;
                        case "Uca线电压":
                            webSocketMsg.sendData("lineVoltageUca", value, boxId, 0, 1);
                            break;
                        case "A相有功功率":
                            webSocketMsg.sendData("phaseAActivePower", value, boxId, 0, 3);
                            break;
                        case "B相有功功率":
                            webSocketMsg.sendData("phaseBActivePower", value, boxId, 0, 3);
                            break;
                        case "C相有功功率":
                            webSocketMsg.sendData("phaseCActivePower", value, boxId, 0, 3);
                            break;
                        case "合相有功功率":
                            webSocketMsg.sendData("totalActivePower", value, boxId, 0, 3);
                            break;
                        case "A相无功功率":
                            webSocketMsg.sendData("phaseAReactivePower", value, boxId, 0, 3);
                            break;
                        case "B相无功功率":
                            webSocketMsg.sendData("phaseBReactivePower", value, boxId, 0, 3);
                            break;
                        case "C相无功功率":
                            webSocketMsg.sendData("phaseCReactivePower", value, boxId, 0, 3);
                            break;
                        case "合相无功功率":
                            webSocketMsg.sendData("totalReactivePower", value, boxId, 0, 3);
                            break;
                        case "A相视在功率":
                            webSocketMsg.sendData("phaseAApparentPower", value, boxId, 0, 3);
                            break;
                        case "B相视在功率":
                            webSocketMsg.sendData("phaseBApparentPower", value, boxId, 0, 3);
                            break;
                        case "C相视在功率":
                            webSocketMsg.sendData("phaseCApparentPower", value, boxId, 0, 3);
                            break;
                        case "合相视在功率":
                            webSocketMsg.sendData("totalApparentPower", value, boxId, 0, 3);
                            break;
                        case "合相功率因数":
                            webSocketMsg.sendData("totalPowerFactor", value, boxId, 0, 2);
                            break;
                        case "冷却风机运行频率":
                            webSocketMsg.sendData("coolingFanOperatingFrequency", value, boxId, 2, 2);
                            break;
                        case "冷却风机运行电流":
                            webSocketMsg.sendData("coolingFanOperatingCurrent", value, boxId, 2, 2);
                            break;
                        case "冷却风机运行功率":
                            webSocketMsg.sendData("coolingFanOperatingPower", value, boxId, 1, 1);
                            break;
                        case "喷淋泵运行频率":
                            webSocketMsg.sendData("sprayPumpOperatingFrequency", value, boxId, 2, 2);
                            break;
                        case "喷淋泵运行电流":
                            webSocketMsg.sendData("sprayPumpOperatingCurrent", value, boxId, 2, 2);
                            break;
                        case "喷淋泵运行功率":
                            webSocketMsg.sendData("sprayPumpOperatingPower", value, boxId, 1, 1);
                            break;
                        case "集水槽温度":
                            webSocketMsg.sendData("waterCollectionTankTemperature", value, boxId, 0, 1);
                            break;
                        case "工频循环泵":
                            webSocketMsg.sendData("frequencyConversionCirculationPumpOperating", value, boxId, 3, 0);
                            break;
                        case "变频循环泵":
                            webSocketMsg.sendData("variableFrequencyCirculationPumpOperating", value, boxId, 3, 0);
                            break;
                        case "加热泵":
                            webSocketMsg.sendData("heatingPumpOperating", value, boxId, 3, 0);
                            break;
                        case "冷却风机":
                            webSocketMsg.sendData("coolingFanOperating", value, boxId, 3, 0);
                            break;
                        case "喷淋泵":
                            webSocketMsg.sendData("sprayPumpOperating", value, boxId, 3, 0);
                            break;
                        case "总电能度数":
                            webSocketMsg.sendData("totalEnergy", value, boxId, 0, 1);
                        case "分钟（记录）":
                            // 0天/0小时/0分钟
                            int totalMinutes = Integer.parseInt(value);
                            int days = totalMinutes / (24 * 60);
                            int remainingMinutes = totalMinutes % (24 * 60);
                            int hours = remainingMinutes / 60;
                            int minutes = remainingMinutes % 60;
                            // 动态构建结果字符串
                            StringBuilder result = new StringBuilder();
                            if (days > 0) {
                                result.append(days).append("天 ");
                            }
                            if (hours > 0) {
                                result.append(hours).append("小时 ");
                            }
                            if (minutes > 0 || result.length() == 0) { // 如果全部为0，至少显示分钟
                                result.append(minutes).append("分钟");

                            }
                            webSocketMsg.sendData("totalMinutes", result.toString().trim(), boxId, 0,0);
                        default:
                            break;
                    }
                }
            });
        });

        // signalr盒子状态变更事件
        hubProxy.subscribe("boxConnStateChanged").addReceivedHandler(jsonElements -> {
            Global.threadPool.submit(() -> {
                if (jsonElements.length <= 0)
                    return;
                BoxStateChanged[] stateChanges = gson.fromJson(jsonElements[0], BoxStateChanged[].class);
                // 335323110285  方舟的deviceNumber
                List<String> boxIds = Arrays.asList("5530935704126782231");
                for (BoxStateChanged stateChange : stateChanges) {
                    // stateChange.id 是盒子列表中BoxReg对象下的box.id，可以根据这个过滤要开的盒子。
                    // stateChange.state 为1是盒子上线事件。
                    //修改电梯状态(0：未知，1：已连接，2：超时，3：已断开)
                    String boxId = stateChange.id;
                    int status = stateChange.state;
                    //过滤要开的盒子
                    if (boxIds.contains(boxId)) {
                        if (status == 1) {
                            try {
                                Global.commServer.executePost("box/" + boxId + "/dmon/start", String.class);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        });
    }
}

